#include "EventLoopThreadPool.h"
#include "EventLoopThread.h"

#include <memory>

EventLoopThreadPool::EventLoopThreadPool(EventLoop *baseLoop, const std::string &nameArg)
    : baseLoop_(baseLoop), name_(nameArg), started_(false), numThreads_(0), next_(0)
{
}

EventLoopThreadPool::~EventLoopThreadPool()
{
    /**
     * 不需要显示释放资源
     * 1. threads_存储的是unique_ptr管理的EventLoopThread，会自动释放EventLoopThread对象
     * 2. EventLoop对象在EventLoopThread的线程栈上创建的，线程结束时会自动销毁
     */
}

void EventLoopThreadPool::start(const ThreadInitCallback &cb)
{
    started_ = true;

    for (int i = 0; i < numThreads_; i++)
    {
        char buf[name_.size() + 32];
        snprintf(buf, sizeof buf, "%s%d", name_.c_str(), i); // 为每个线程生成唯一名称：主线程名+线程编号
        EventLoopThread *t = new EventLoopThread(cb, buf);
        threads_.push_back(std::unique_ptr<EventLoopThread>(t)); // 将每一个EventLoopThread存入threads_

        // 启动每一个EventLoopThread并将返回的EventLoop*存入loops_
        loops_.push_back(t->startLoop()); // 底层启动创建线程，绑定一个新的EventLoop，并返回该loop的地址
    }

    // 如果线程数为0表示整个服务端只有一个主线程线程，直接在主线程的baseLoop_上执行初始化回调
    if (numThreads_ == 0 && cb)
    {
        cb(baseLoop_);
    }
}

// 如果工作在多线程中，baseLoop_默认以轮询的方式分配Channel给subLoop
EventLoop *EventLoopThreadPool::getNextLoop()
{
    EventLoop *loop = baseLoop_;
    if (!loops_.empty()) // 通过轮询（按顺序循环）获取下一个处理事件的loop
    {
        loop = loops_[next_];
        ++next_;
        if (next_ > loops_.size())
        {
            next_ = 0;
        }
    }

    return loop;
}

std::vector<EventLoop *> EventLoopThreadPool::getAllLoops()
{
    if (loops_.empty())
    {
        return std::vector<EventLoop *>(1, baseLoop_);
    }
    else
    {
        return loops_;
    }
}